compile in gpsbabel translations and map on non mac unix distribution… (#622)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Fri, 14 Aug 2020 22:41:03 +0000 (16:41 -0600)
committerGitHub <noreply@github.com>
Fri, 14 Aug 2020 22:41:03 +0000 (16:41 -0600)
* compile in gpsbabel translations and map on non mac unix distributions by default.

This eliminates the need to install gpsbabelfe_*.qm, gpsbabel_*.qm and
gmapbase.html on the system.
Note that the Qt supplied translations must still be installed on the system.
The Qt translations may be in a package like qttranslations5-l10n or
qt5-qttranslations.

* simplify optional resources using std methods.

* discuss dependencies in INSTALL.

INSTALL
gui/app.pro
gui/mainwindow.cc
gui/mainwindow.h
gui/map.cc
gui/map.qrc [new file with mode: 0644]
gui/translations.qrc [new file with mode: 0644]

diff --git a/INSTALL b/INSTALL
index 06faf40b7aabc9d5b5eea8b952662d1f2006199a..9f7da6c31aaaca750852c0e79c9f625bc6870f0a 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -57,6 +57,14 @@ unix-gui: Build the graphical user interface and collect the components for
   On macOS an app bundle will be created at gui/GPSBabelFE.app and an apple disk
   image will be created at gui/GPSBabelFE.dmg.
 
+Dependencies:
+On non-macOS unix builds by default we now compile in the gpsbabel generated
+translation files, i.e. gpsbabelfe_*.qm, gpsbabel_*.qm, as well as
+gmapbase.html.  When compiled in these files do not need to be distributed.
+These are used by the GUI.  Additional translation files from Qt will also be
+used if they are found.  They may be in a package such as qttranslations5-l10n
+or qt5-qttranslations.
+
 Windows builds:
   Two build methods are supported with MSVC tools.
   1. "qmake -tp vc" will create a visual studio project that can be built with msbuild.
index 4daefde480070b27a62304a4e2177057a6e8bced..bf359612aecfd0b6c4a7bebbb2be3b81e2e27b68 100755 (executable)
@@ -18,7 +18,7 @@ qtHaveModule(webenginewidgets) {
   QT += webenginewidgets webchannel
   DEFINES += HAVE_WEBENGINE
 } else {
-  QT += webkit webkitwidgets 
+  QT += webkit webkitwidgets
 }
 
 unix:DESTDIR = objects
@@ -38,10 +38,10 @@ unix {
 
 UI_DIR = tmp
 
-RESOURCES = app.qrc 
+RESOURCES = app.qrc
 RC_FILE = app.rc
 
-win32 { 
+win32 {
   TARGET=GPSBabelFE
 }
 win32-g++ {
@@ -125,6 +125,17 @@ TRANSLATIONS += gpsbabelfe_fr.ts
 TRANSLATIONS += gpsbabelfe_hu.ts
 TRANSLATIONS += gpsbabelfe_it.ts
 
+unix:!mac {
+  !defined(EMBED_TRANSLATIONS, var):EMBED_TRANSLATIONS = on
+  !defined(EMBED_MAP, var):EMBED_MAP = on
+}
+equals(EMBED_TRANSLATIONS, on) {
+  RESOURCES += translations.qrc
+}
+equals(EMBED_MAP, on) {
+  RESOURCES += map.qrc
+}
+
 macx|linux{
   package.commands = QMAKE=$(QMAKE) ./package_app
   package.depends = $(TARGET)
index 22b2b449c2a9552a413462824df253cb1d7e5031..52bd16b64e4c569657dc9a2cc30e487e1df9ac4f 100644 (file)
 #include <QtCore/QEvent>               // for QEvent (& QEvent::LanguageChange, QEvent::LocaleChange)
 #include <QtCore/QFile>                // for QFile
 #include <QtCore/QFileInfo>            // for QFileInfo
+#include <QtCore/QLibraryInfo>         // for QLibraryInfo, QLibraryInfo::TranslationsPath
 #include <QtCore/QLocale>              // for QLocale
 #include <QtCore/QMimeData>            // for QMimeData
 #include <QtCore/QProcess>             // for QProcess, QProcess::NotRunning
 #include <QtCore/QRegExp>              // for QRegExp
 #include <QtCore/QSettings>            // for QSettings
+#include <QtCore/QString>              // for QString
+#include <QtCore/QStringList>          // for QStringList
 #include <QtCore/QTemporaryFile>       // for QTemporaryFile
 #include <QtCore/QTime>                // for QTime
 #include <QtCore/QUrl>                 // for QUrl
@@ -219,9 +222,6 @@ MainWindow::MainWindow(QWidget* parent): QMainWindow(parent)
 
   ui_.outputWindow->setReadOnly(true);
 
-  langPath_ = QApplication::applicationDirPath();
-  langPath_.append("/translations/");
-
   // Start up in the current system language.
   loadLanguage(QLocale::system().name());
   loadFormats();
@@ -311,9 +311,25 @@ void MainWindow::switchTranslator(QTranslator& translator, const QString& filena
   // remove the old translator
   qApp->removeTranslator(&translator);
 
-  // load the new translator
-  if (translator.load(filename, langPath_)) {
-    qApp->installTranslator(&translator);
+  // Set a list of locations to search for the translation file.
+  // 1. In the file system in the translations directory relative to the
+  //    location of the executable.
+  // 2. In the Qt resource system under the translations path.  This is useful
+  //    if the resource was compiled into the executable.
+  // 3. In the translations path for Qt.  This is useful to find translations
+  //    included with Qt.
+  const QStringList directories = {
+    QApplication::applicationDirPath() + "/translations",
+    ":/translations",
+    QLibraryInfo::location(QLibraryInfo::TranslationsPath)
+  };
+
+  // Load the new translator.
+  for (const auto& directory : directories) {
+    if (translator.load(filename, directory)) {
+      qApp->installTranslator(&translator);
+      break;
+    }
   }
 }
 
index 3fd107fbf8431423c62ce8049147a28b395cf230..b6de39944f4b7718a7d30c3902a729e7d32bd2b3 100644 (file)
@@ -70,7 +70,6 @@ private:
   QTranslator     translatorCore_; // translation for the core application.
   QTranslator     translatorQt_;   // translations for Qt.
   QString         currLang_;       // currently loaded language.
-  QString         langPath_;       // Absolute path of language files.
 
 private:
   void loadFormats();
index a55c752e356e3551d7e5b9c40381079eb9ce83d6..aac5d5729e6089ea07200b934f57f581bfd7a82a 100644 (file)
@@ -90,13 +90,18 @@ Map::Map(QWidget* parent,
   connect(mclicker, SIGNAL(logTime(QString)), this, SLOT(logTime(QString)));
 #endif
 
+  // We search the following locations:
+  // 1. In the file system in the same directory as the executable.
+  // 2. In the Qt resource system.  This is useful if the resource was compiled
+  //    into the executable.
   QString baseFile =  QApplication::applicationDirPath() + "/gmapbase.html";
-  if (!QFile(baseFile).exists()) {
+  if (QFile(baseFile).exists()) {
+    this->load(QUrl::fromLocalFile(baseFile));
+  } else if (QFile(":/gmapbase.html").exists()) {
+    this->load(QUrl("qrc:///gmapbase.html"));
+  } else {
     QMessageBox::critical(nullptr, appName,
                           tr("Missing \"gmapbase.html\" file.  Check installation"));
-  } else {
-    QString urlStr = "file:///" + baseFile;
-    this->load(QUrl(urlStr));
   }
 
 #ifdef DEBUG_JS_GENERATION
diff --git a/gui/map.qrc b/gui/map.qrc
new file mode 100644 (file)
index 0000000..f683dda
--- /dev/null
@@ -0,0 +1,5 @@
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource>
+     <file>gmapbase.html</file>
+ </qresource>
+ </RCC>
diff --git a/gui/translations.qrc b/gui/translations.qrc
new file mode 100644 (file)
index 0000000..582eeca
--- /dev/null
@@ -0,0 +1,16 @@
+ <!DOCTYPE RCC><RCC version="1.0">
+ <qresource>
+     <file alias="translations/gpsbabel_de.qm">coretool/gpsbabel_de.qm</file>
+     <file alias="translations/gpsbabel_es.qm">coretool/gpsbabel_es.qm</file>
+     <file alias="translations/gpsbabel_fr.qm">coretool/gpsbabel_fr.qm</file>
+     <file alias="translations/gpsbabel_hu.qm">coretool/gpsbabel_hu.qm</file>
+     <file alias="translations/gpsbabel_it.qm">coretool/gpsbabel_it.qm</file>
+     <file alias="translations/gpsbabel_ru.qm">coretool/gpsbabel_ru.qm</file>
+     <file alias="translations/gpsbabelfe_de.qm">gpsbabelfe_de.qm</file>
+     <file alias="translations/gpsbabelfe_es.qm">gpsbabelfe_es.qm</file>
+     <file alias="translations/gpsbabelfe_fr.qm">gpsbabelfe_fr.qm</file>
+     <file alias="translations/gpsbabelfe_hu.qm">gpsbabelfe_hu.qm</file>
+     <file alias="translations/gpsbabelfe_it.qm">gpsbabelfe_it.qm</file>
+     <file alias="translations/gpsbabelfe_ru.qm">gpsbabelfe_ru.qm</file>
+ </qresource>
+ </RCC>